package threadUtils.demo02;

import threadUtils.Person;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

/**
 * CyclicBarrier工具类的特殊用户。多次使用。
 * 模拟用户等车，清点人数，上车，开车，下车，清点人数，停车这个流程。
 * 用CyclicBarrier的多线程工具类来模拟多次使用的功能
 */
public class CyclicBarrierExample02 {

    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {

        // 10个人
        List<Person> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new Person("x" + i, i));
        }
        CyclicBarrier cyclicBarrier = new CyclicBarrier(list.size() + 1);
        list.forEach(person -> {
            new Thread(() -> {
                // 等车
                System.out.printf("People: %d by bus \n", person.getId());

                // 上车
                try {
                    TimeUnit.MILLISECONDS.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    System.out.printf("Person: %d Get on bus, and wait other people \n", person.getId());
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        });
        cyclicBarrier.await();
        System.out.println("All people get on the bus");

        list.forEach(person -> {
            new Thread(() -> {
                System.out.printf("People: %d 行程中 \n", person.getId());
                // 下车
                try {
                    TimeUnit.MILLISECONDS.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    System.out.printf("People: %d Get off the bus, and wait the other people \n", person.getId());
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        });
        cyclicBarrier.await();
        System.out.println("All people get off the bus");


    }

}